require 'erb'
require 'common/base'

# Connectivity Fault Management  (CFM) comprises capabilities for
# detecting, verifying, and isolating connectivity failures in Virtual Bridged Local Area Networks. 

class CFMBase < Base

  attr_accessor :step, :transport, :base_hosts, :base_options, :base_transports, :base_variables, :message, :vlan_identifier, :cfm_header

  def initialize(step, filename, params = {}, transport="CFM")
    super()
    @transport = transport
    @step = step

    @vlan_identifier = params["vlan_identifier"] or "0"
    @egress_identifier = params["egress_identifier"] or "0000000000000000"
    @mepid = params["mepid"] or "0"
    @maid = params["maid"] or "0"
    @ttl = params["ttl"] or "64"
    @chassis = params["chassis"] or "000000000000"
    @interface_status = params["interface_status"] or "0"
    @oam_info_oui = params["oam_info_oui"] or "000000"
    @src_mac = params["src_mac"] or "000000000000"
    @target_mac = params["target_mac"] or "000000000000"

    @base_hosts ='&host_0 = host(role: "client", description: "client/src", type: l2)
        &host_1 = host(role: "server", description: "server/dst", type: l2)
    '

    @base_options = "
     $maid = '<%= @maid %>'
     $mepid = '<%= @mepid %>'
     $chassis = '<%= @chassis %>'
     $interface_status = '<%= @interface_status %>'
     $oam_info_oui = '<%= @oam_info_oui %>'
     $egress_identifier = '<%= @egress_identifier %>'"

    @base_variables = '@seq_num = random_integer(4)'

    @base_transports = 'CFM = ethernet(src: &host_0, dst: &host_1, filter: "(ether dst src_mac or ether broadcast) and ether proto 0x88a8", type: 0x88a8)'

    if !filename.nil?
      set_cfm_header(filename)
      template = get_message("CFM", filename)
      erb = ERB.new(template, 0, '%<>')
      @message = erb.result(binding)
    end
  end

  def set_cfm_header(filename)
    md_level = 0
    opcode = 0
    flags = 0
    tlv_offset = 0

    case filename
     when "CFMLoopbackReply"
       md_level = 0
       opcode = 3
       flags = 0
       tlv_offset = 4
     when "CFMLinkTraceReply"
       md_level = 0
       opcode = 4
       flags = 8
       tlv_offset = 6
     when "CFMLoopbackMessage"
       md_level = 0
       opcode = 3
       flags = 0
       tlv_offset = 4
     when "CFMLinkTraceMessage"
       md_level = 0
       opcode = 5
       flags = 8
       tlv_offset = 17
    when "CFMContinuityCheckMessage"
       md_level = 3
       opcode = 1
       flags = 4  # see below, if 1 => RDI=0, Reserved=0000, CCM Interval=003
       tlv_offset = 70
    end

    @cfm_header = CommonCFMHeader.new(self, md_level, opcode, flags, tlv_offset).message
  end
end
